<template>
  <div class="container">
    <a-card class="general-card" title="用户管理">
      <a-row>
        <a-col v-permission="'system:user:query'" :span="4">
          <dept-tree-search @select-data="treeSelect"></dept-tree-search>
        </a-col>
        <a-col :span="20">
          <table-search
            v-permission="'system:user:query'"
            :fileds="searchFileds"
            :label-col-props="{ span: 7 }"
            :wrapper-col-props="{ span: 17 }"
            @search="search"
            @reset="search"
          ></table-search>
          <xTable
            v-model:refresh="refresh"
            v-model:selected-keys="selectedKeys"
            :params="params"
            :columns="tableColumns"
            row-key="userId"
            :http="{
              list: getListData,
              exported: user,
              del: delUser,
              batchDel: delUser,
            }"
            :http-permission="{
              exported: 'system:user:export',
              del: 'system:user:remove',
            }"
            :import-config="importConfig"
          >
            <template #operation-default>
              <div class="item">
                <a-button
                  v-permission="'system:user:add'"
                  type="outline"
                  @click="editOpen(null)"
                >
                  新增
                </a-button>
              </div>
              <div class="item">
                <a-button
                  v-permission="'system:user:edit'"
                  type="outline"
                  status="success"
                  @click="editOpen(selectedKeys)"
                >
                  编辑
                </a-button>
              </div>
            </template>
            <template #optional="{ row }">
              <a-button
                v-permission="'system:user:edit'"
                type="text"
                status="success"
                @click="editOpen(row.userId)"
              >
                编辑
              </a-button>
              <a-button
                v-permission="'system:user:resetPwd'"
                type="text"
                status="warning"
                @click="resetOpen(row.userId)"
              >
                重置密码
              </a-button>
            </template>
          </xTable>
        </a-col>
      </a-row>
    </a-card>
    <EditModal
      ref="edit"
      :default-value="{ password: '123456', status: defaultStatus }"
      :http-add="addUser"
      :http-edit="updateUser"
      :http-get="getUser"
      :fields="editFields"
      :get-handler="getHandler"
      @reload="refresh = true"
    >
    </EditModal>
    <EditModal
      ref="resetPass"
      edit-title="重置密码"
      :http-edit="resetUserPwd"
      :fields="resetEditFields"
      @reload="refresh = true"
    >
    </EditModal>
  </div>
</template>

<script lang="ts" setup>
  import { reactive, ref, computed, toRaw } from 'vue';
  import { addDateRange } from '@/utils/index';
  import {
    getListData,
    getUser,
    addUser,
    updateUser,
    delUser,
    resetUserPwd,
  } from '@/api/system/user';
  import { treeselect as deptTreeSelect } from '@/api/system/dept';
  import { user, userImportTemplate } from '@/api/exportFile';
  import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
  import { Message } from '@arco-design/web-vue';
  import { getDict } from '@/utils/dict';

  const dict = getDict('sys_normal_disable', 'sys_user_sex');
  const edit = ref();
  const resetPass = ref();
  const selectedKeys = ref([]);
  const deptTree: any = ref([]);
  const postList: any = ref([]);
  const roleList: any = ref([]);
  const importConfig: any = ref({
    url: `${import.meta.env.VITE_API_BASE_URL}/system/user/importData`,
    title: '导入用户',
    width: '500px',
    template: userImportTemplate,
    permission: 'system:user:import',
  });
  // 定义查询字段
  const searchFileds: Array<any> = reactive([
    {
      span: 6,
      field: 'userName',
      placeholder: '请输入用户名称',
      label: '用户名称',
      tag: 'a-input',
      initValue: '',
    },
    {
      span: 6,
      field: 'phonenumber',
      placeholder: '请输入手机号码',
      label: '手机号码',
      tag: 'a-input',
      initValue: '',
    },
    {
      span: 6,
      field: 'status',
      placeholder: '请选择角色状态',
      label: '状态',
      initValue: '',
      tag: 'a-select',
      attrs: {
        options: [
          { value: '1', label: '开启' },
          { value: '2', label: '禁用' },
        ],
      },
    },
    {
      span: 6,
      field: 'dateRange',
      label: '创建时间',
      tag: 'a-range-picker',
      initValue: [],
    },
  ]);
  // 定义表格字段
  const tableColumns: Array<TableColumnData> = reactive([
    {
      dataIndex: 'userId',
      title: '用户编号',
    },
    {
      dataIndex: 'userName',
      title: '用户名称',
    },
    {
      dataIndex: 'nickName',
      title: '用户昵称',
    },
    {
      dataIndex: 'deptName',
      title: '部门',
    },
    {
      dataIndex: 'phonenumber',
      title: '手机号码',
    },
    {
      dataIndex: 'status',
      title: '状态',
    },
    {
      dataIndex: 'createTime',
      title: '创建时间',
    },
    {
      dataIndex: 'optional',
      title: '创建时间',
      slotName: 'optional',
    },
  ]);

  const editFields: Array<any> = reactive([
    {
      key: 'nickName',
      label: '用户昵称',
      tag: 'a-input',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 16 },
      },
      placeholder: '请输入用户昵称',
      decorator: {
        rules: [{ required: true, message: '请输入用户昵称', trigger: 'blur' }],
      },
    },
    {
      key: 'deptId',
      label: '归属部门',
      tag: 'a-tree-select',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 16 },
      },
      attrs: {
        'data': deptTree,
        'treeProps': {
          virtualListProps: {
            height: 200,
          },
        },
        'field-names': {
          key: 'id',
          title: 'label',
        },
        'allow-search': true,
        'allow-clear': true,
        'filter-tree-node': (
          searchValue: string,
          nodeData: { title: string }
        ) => {
          return (
            String(nodeData.title)
              .toLowerCase()
              .indexOf(String(searchValue).toLowerCase()) > -1
          );
        },
      },
      placeholder: '请选择归属部门',
      decorator: {
        rules: [{ required: false, message: '请选择归属部门' }],
      },
    },
    {
      key: 'phonenumber',
      label: '手机号码',
      tag: 'a-input',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 16 },
      },
      placeholder: '请输入手机号码',
      decorator: {
        rules: [
          { required: false, message: '请输入手机号码' },
          {
            match: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
            message: '请输入正确的手机号码',
            trigger: 'blur',
          },
        ],
      },
    },
    {
      key: 'email',
      label: '邮箱',
      tag: 'a-input',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 16 },
      },
      placeholder: '请输入邮箱',
      decorator: {
        rules: [
          { required: false, message: '请输入邮箱' },
          {
            type: 'email',
            message: '请输入正确的邮箱地址',
            trigger: ['blur', 'change'],
          },
        ],
      },
    },
    {
      key: 'userName',
      label: '用户名称',
      tag: 'a-input',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 16 },
      },
      placeholder: '请输入用户名称',
      decorator: {
        rules: [
          { required: true, message: '请输入用户名称' },
          {
            minLength: 2,
            maxLength: 20,
            message: '用户名称长度必须介于 2 和 20 之间',
            trigger: 'blur',
          },
        ],
      },
    },
    {
      key: 'password',
      label: '用户密码',
      tag: 'a-input-password',
      span: 12,
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 16 },
      },
      placeholder: '请输入用户密码',
      decorator: {
        rules: [
          { required: true, message: '请输入用户密码' },
          {
            minLength: 5,
            maxLength: 20,
            message: '用户密码长度必须介于 5 和 20 之间',
            trigger: 'blur',
          },
        ],
      },
      show: (value: any) => {
        if (value?.userId) {
          return false;
        }
        return true;
      },
    },
    {
      key: 'sex',
      label: '用户性别',
      tag: 'a-select',
      span: 12,
      attrs: {
        options: dict.sys_user_sex,
      },
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 16 },
      },
      placeholder: '请选择用户性别',
      decorator: {
        rules: [{ required: false, message: '请选择用户性别' }],
      },
    },
    {
      key: 'status',
      label: '状态',
      tag: 'a-radio-group',
      span: 12,
      attrs: {
        options: dict.sys_normal_disable,
      },
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 16 },
      },
      placeholder: '请选择状态',
      decorator: {
        rules: [{ required: false, message: '请选择状态' }],
      },
    },
    {
      key: 'postIds',
      label: '岗位',
      tag: 'a-select',
      span: 12,
      attrs: {
        options: postList,
        multiple: true,
      },
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 16 },
      },
      placeholder: '请选择岗位',
      decorator: {
        rules: [{ required: false, message: '请选择岗位' }],
      },
    },
    {
      key: 'roleIds',
      label: '角色',
      tag: 'a-select',
      span: 12,
      attrs: {
        options: roleList,
        multiple: true,
      },
      formItemAttrs: {
        'label-col-props': { span: 8 },
        'wrapper-col-props': { span: 16 },
      },
      placeholder: '请选择角色',
      decorator: {
        rules: [{ required: false, message: '请选择角色' }],
      },
    },
    {
      key: 'remark',
      label: '备注',
      tag: 'a-textarea',
      span: 24,
      placeholder: '请输入备注',
      decorator: {
        rules: [{ required: false, message: '请输入备注' }],
      },
    },
  ]);
  const resetEditFields: Array<any> = reactive([
    {
      key: 'password',
      label: '用户密码',
      tag: 'a-input-password',
      placeholder: '请输入用户密码',
      decorator: {
        rules: [
          { required: true, message: '请输入用户密码' },
          {
            minLength: 5,
            maxLength: 20,
            message: '用户密码长度必须介于 5 和 20 之间',
            trigger: 'blur',
          },
        ],
      },
    },
  ]);
  const refresh = ref(true);
  // 定义表格查询参数
  const params = ref({
    dateRange: [],
    deptId: null,
  });

  const defaultStatus = computed(() => {
    if (dict.sys_normal_disable.value <= 0) {
      return '0';
    }
    const list = toRaw(dict.sys_normal_disable);
    return list.value.find((item: { default: any }) => item.default).value;
  });
  // 定义搜索方法
  const search = (data: any) => {
    params.value = { ...params.value, ...addDateRange(data, data?.dateRange) };
    refresh.value = true;
  };
  const treeSelect = (e: any) => {
    params.value.deptId = e;
    refresh.value = true;
  };

  const editOpen = async (keys: any | any[]) => {
    if (Array.isArray(keys) && keys.length === 1) {
      edit.value.show(keys[0]);
    } else if (!Array.isArray(keys)) {
      edit.value.show(keys);
    } else if (Array.isArray(keys) && keys.length < 1) {
      Message.warning('必须选中一条数据');
    } else if (Array.isArray(keys) && keys.length > 1) {
      Message.warning('只能选中一条数据');
    }
  };
  const resetOpen = async (keys: any | any[]) => {
    resetPass.value.show(keys);
  };
  const getHandler = (data: { [x: string]: any; postIds: any; data: any }) => {
    return {
      ...data.data,
      postIds: data.postIds,
      roleIds: data.roleIds,
    };
  };
  const initSelectData = async () => {
    const deptRes = await deptTreeSelect();
    if (deptRes.code !== 200) {
      Message.error(deptRes.msg);
      return;
    }
    deptTree.value = deptRes.data;
    const userRes = await getUser('');
    if (userRes.code !== 200) {
      Message.error(userRes.msg);
      return;
    }
    postList.value = userRes.posts.map(
      (item: { postName: any; postId: any }) => ({
        ...item,
        label: item.postName,
        value: item.postId,
      })
    );
    roleList.value = userRes.roles.map(
      (item: { roleName: any; roleId: any }) => ({
        ...item,
        label: item.roleName,
        value: item.roleId,
      })
    );
  };
  initSelectData();
</script>

<script lang="ts">
  export default {
    name: 'SearchTable',
  };
</script>

<style scoped lang="less">
  .operation-bar {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    margin-bottom: 20px;
    .item {
      margin-left: 8px;
    }
  }
  .container {
    // padding: 0 20px 20px 20px;
  }
  :deep(.arco-table-th) {
    &:last-child {
      .arco-table-th-item-title {
        margin-left: 16px;
      }
    }
  }
</style>
